<?php

namespace App\Trip\Plane\Log;

use App;
use App\Jobs\Plane\ProcessTicketQueryLog;
use Carbon\Carbon;
use Illuminate\Support\Facades\Cache;
use JetBrains\PhpStorm\ArrayShape;

class TicketQueryLog
{
    private string $cache_key;
    private string $cache_key2;
    private int    $cache_time;
    private        $from;
    private        $to;
    private string $date;
    private string $ip;
    /**
     * @var  int
     */
    private int $push_time;
    private int $valid_time;

    public function __construct($from, $to, string $date, string $ip)
    {
        // 为了保证数据不丢失 last_key  缓存时间 比推送时间多1小时
        $time             = Carbon::now()->diffInSeconds(Carbon::tomorrow());
        $this->cache_time = $time + Hours2Seconds();
        $this->push_time  = $time;
        $this->valid_time = Minutes2Seconds();
        if (App::isLocal()) {
            $this->push_time  = min(20, $this->cache_time);
            $this->valid_time = 5;
        }
        $this->cache_key  = "Plane:QueryLog:{$from['code']}:{$to['code']}:{$date}:$ip";
        $this->cache_key2 = "Plane:QueryLog:{$from['code']}:{$to['code']}:{$date}:$ip:Last";
        $this->from       = $from;
        $this->to         = $to;
        $this->date       = $date;
        $this->ip         = $ip;
    }

    public function getFrom(): array
    {
        return $this->from;
    }

    public function getTo(): array
    {
        return $this->to;
    }

    #[ArrayShape(['from_code' => "mixed|string", 'from_type' => "int|mixed", 'to_code' => "mixed|string", 'to_type' => "int|mixed", 'date' => "", 'count' => "int|mixed", 'ip_address' => ""])]
    public function toArray(): array
    {
        return [
            'from_code'  => $this->from['code'],
            'from_type'  => $this->from['type'],
            'to_code'    => $this->to['code'],
            'to_type'    => $this->to['type'],
            'date'       => $this->getDate(),
            'count'      => $this->getQueryCount(),
            'ip_address' => $this->getIpAddress(),
        ];
    }

    public function getDate(): string
    {
        return $this->date;
    }

    public function getQueryCount()
    {
        return Cache::get($this->cache_key) ?: 0;
    }

    public function getIpAddress(): string
    {
        return $this->ip;
    }

    public function cacheAndPushQueue(): static
    {
        // 60秒内 算一个
        $ck = "{$this->cache_key}:ValidTime";
        if (Cache::has($ck)) {
            return $this;
        }
        Cache::put($ck, 1, $this->valid_time);
        // 跨天不处理
        if (Carbon::today()->notEqualTo(Carbon::parse($this->date))) {
            return $this;
        }

        if (Cache::has($this->cache_key)) {
            Cache::increment($this->cache_key, 1);
        } else {
            Cache::put($this->cache_key, 1, $this->cache_time);
        }

        Cache::put($this->cache_key2, Cache::get($this->cache_key), $this->cache_time);
        // 延时队列
        ProcessTicketQueryLog::dispatch($this)->delay(now()->addSeconds($this->push_time));

        return $this;
    }

    public function isValid(): bool
    {
        $curr = $this->getQueryCount();
        $max  = $this->getMaxQueryCount();
        if ($curr == 0 || $max == 0) {
            return false;
        }

//        if ($max >= $curr) {
//            // 失效其他的并返回
//
//            return true;
//        }
        return $max >= $curr;
    }

    public function getMaxQueryCount()
    {
        return Cache::get($this->cache_key2) ?: 0;
    }
}